<template>
  <article>
    <el-card>
      <div slot="header" class="clearfix">
        <span>用户菜单</span>
        <el-button type="text">
          {{ username }}
        </el-button>
      </div>
      <div v-for="(m, i) in menus" :key="i" class="item">
        <span @click.prevent="toPath(m.path)">{{ m.name }}</span>
        <div
          v-for="(c, j) in m.children"
          :key="j"
          @click.stop="toPath(c.path)"
          class="text"
        >
          {{ c.name }}
        </div>
      </div>
    </el-card>
  </article>
</template>

<script>
// 引入VueRouter
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
// 引入公共路由文件commonRoutes，避免产生一些路由问题，如退出时无页面
import { commonRoutes } from "../utils/commonRoutes";
import { formatRoutes } from "../utils/formatRoutes";
export default {
  data() {
    return {
      menus: [],
      username: "",
    };
  },
  async created() {
    // 先判断是否存在用户信息
    const userInfo = JSON.parse(sessionStorage.getItem("userInfo"));
    if (userInfo) {
      this.username = userInfo.username;
    } else {
      this.$message({
        type: "error",
        message: "请重新登录！",
      });
      this.$router.push("/login");
      return false;
    }
    // 获取本地菜单
    let menuData = JSON.parse(sessionStorage.getItem("menuData"));
    // 无本地菜单时
    if (!menuData) {
      this.$message({
        type: "warning",
        message: "获取菜单失败，重新获取菜单！",
      });
      //重新获取菜单
      const { data: res } = await this.$http({
        url: "/getMenus",
        method: "post",
        data: userInfo,
      });
      menuData = res.result;
      sessionStorage.setItem("menuData", JSON.stringify(menuData));
    }
    if (menuData.length) {
      const routeData = formatRoutes(menuData);
      const logout = { path: "/logout", name: "退出登录" };
      this.menus = [...routeData, logout];
      // 404页面
      const err = { path: "*", name: "err", component: () => import("comps/404.vue") };
      // getRoute逐层拿出-避免嵌套路由无效
      const routerArr = [this.getRoute(routeData), err, commonRoutes];
      // 多维数组拉平成一维数组
      const userMenus = routerArr.flat(Infinity);
      //重新实例化一个VueRouter，解决路由重复报警告问题
      const router = new VueRouter();
      // 重置VueRouter中的matcher
      this.$router.matcher = router.matcher;
      // 进行路由添加-在VueRouter4中addRoutes已废弃，能使用但会报警告
      // this.$router.addRoutes(userMenus);
      this.myAddRoutes(userMenus, this);
    } else {
      Message.error("读取菜单失败！");
    }
  },
  methods: {
    toPath(url) {
      if (url == "/home") url = "/";
      //退出登录
      if (url == "/logout") {
        // 清空本地所有信息
        sessionStorage.clear();
        this.$router.push("/login");
        return false;
      }
      //判断为当前路由则刷新
      if (this.$router.currentRoute.path == url) {
        this.$router.go(0);
      } else {
        //否则跳转
        this.$router.push(url);
      }
    },
    // 逐层拿出-避免嵌套路由无效，同时方便addRoute
    getRoute(routeArr) {
      return routeArr.map((route) => {
        let newRoute = route;
        // 如果存在子页面则再次调用此函数
        if (route.children) {
          newRoute = {
            name: route.name,
            path: route.path,
            component: route.component,
          };
          newRoute = [newRoute, this.getRoute(route.children)];
        }
        return newRoute;
      });
    },
    // 由于VueRouter4废弃addRoutes，虽然能使用但会报警告，此处用addRoute代替
    myAddRoutes(routes, that) {
      // 注意：此处的this为undefined
      routes.forEach((route) => {
        that.$router.addRoute(route);
      });
    },
  },
};
</script>
<style scoped>
.item {
  margin-bottom: 18px;
  cursor: pointer;
}
.text {
  padding: 15px;
  padding-bottom: 0;
}
.el-button {
  float: right;
  padding: 3px 0;
  font-size: 16px;
  font-weight: 700;
}
</style>
